<template>
  <div>
    <a-table size="middle"
             :data-source="list"
             :columns="columns"
             :pagination="false"
             bordered
             rowKey="id"
             :row-selection="rowSelection">
      <template slot="title">
        <a-space>
          <!-- <a-input v-model="listQuery['name']" @pressEnter="loadData" placeholder="名称" class="search-input-item" /> -->
          <div>
            显示所有
            <a-switch checked-children="是"
                      un-checked-children="否"
                      v-model="listQuery['showAll']" />
          </div>
          <div>
            悬空
            <a-switch checked-children="是"
                      un-checked-children="否"
                      v-model="listQuery['dangling']" />
          </div>
          <a-button type="primary"
                    @click="loadData"
                    :loading="loading">搜索</a-button>
          <a-button type="danger"
                    :disabled="!tableSelections || !tableSelections.length"
                    @click="batchDelete">批量删除</a-button>
        </a-space>
        |
        <a-button type="primary"
                  @click="constructImage">构建镜像</a-button>
        <!-- <a-input-search v-model="pullImageName"
                        @search="pullImage"
                        style="width: 260px"
                        placeholder="要拉取的镜像名称"
                        class="search-input-item">
          <a-button slot="enterButton"> <a-icon type="cloud-download" /> </a-button>
        </a-input-search> -->
        <!-- <a-button type="primary" @click="pullImage">拉取</a-button> -->
      </template>

      <a-tooltip slot="repoTags"
                 slot-scope="text"
                 placement="topLeft"
                 :title="(text || []).join(',')">
        <span>{{ (text || []).join(",") }}</span>
      </a-tooltip>
      <a-tooltip slot="size"
                 slot-scope="text, record"
                 placement="topLeft"
                 :title="renderSize(text) + ' ' + renderSize(record.virtualSize)">
        <span>{{ renderSize(text) }}</span>
      </a-tooltip>

      <a-tooltip slot="tooltip"
                 slot-scope="text"
                 placement="topLeft"
                 :title="text">
        <span>{{ text }}</span>
      </a-tooltip>

      <a-tooltip slot="id"
                 slot-scope="text"
                 :title="text">
        <span> {{ text && text.split(":")[1].slice(0, 12) }}</span>
      </a-tooltip>
      <template slot="operation"
                slot-scope="text, record">
        <a-space>
          <!-- <a-tooltip title="停止" v-if="record.state === 'running'">
          <a-button size="small" type="link" @click="doAction(record, 'stop')"><a-icon type="stop" /></a-button>
        </a-tooltip>
        <a-tooltip title="启动" v-else>
          <a-button size="small" type="link" @click="doAction(record, 'start')"> <a-icon type="play-circle" /></a-button>
        </a-tooltip>
        -->
          <a-tooltip title="使用当前镜像创建一个容器">
            <a-button size="small"
                      type="link"
                      @click="createContainer(record)"><a-icon type="select" /></a-button>
          </a-tooltip>
          <!-- <a-tooltip title="更新镜像">
            <a-button size="small"
                      type="link"
                      :disabled="!record.repoTags"
                      @click="tryPull(record)"><a-icon type="cloud-download" /></a-button>
          </a-tooltip> -->

          <a-tooltip title="删除镜像">
            <a-button size="small"
                      type="link"
                      @click="doAction(record, 'remove')"><a-icon type="delete" /></a-button>
          </a-tooltip>

          <a-tooltip title="下载镜像">
            <a-button size="small"
                      type="link"
                      @click="handleDowload(record)"><a-icon type="download" /></a-button>
          </a-tooltip>

        </a-space>
      </template>
    </a-table>

    <a-drawer destroyOnClose
              :visible="buildVisible"
              @close="
        () => {
          this.buildVisible = false;
        }
      "
              width="60vw"
              title="构建容器"
              :maskClosable="false">
      <BuildContainer :id="this.id"
                      :imageId="this.temp.id"
                      :machineDockerId="this.machineDockerId"
                      :urlPrefix="this.urlPrefix"
                      @cancelBtnClick="
          () => {
            this.buildVisible = false;
          }
        "
                      @confirmBtnClick="
          () => {
            this.buildVisible = false;
            this.loadData();
          }
        " />
    </a-drawer>
    <!-- 日志 -->
    <a-modal destroyOnClose
             :width="'80vw'"
             v-model="logVisible"
             title="pull日志"
             :footer="null"
             :maskClosable="false">
      <pull-image-Log v-if="logVisible"
                      :id="temp.id"
                      :machineDockerId="this.machineDockerId"
                      :urlPrefix="this.urlPrefix" />
    </a-modal>

    <!-- 构建镜像 -->
    <a-modal destroyOnClose
             :width="'50vw'"
             v-model="constructVisivle"
             title="构建镜像"
             ok-text="确认"
             cancel-text="取消"
             :maskClosable="false"
             @ok="handleOk"
             @cancel="handleCancel">
      <div>

        <a-form-model ref="constructForm"
                      :rules="rules"
                      :model="constructForm"
                      :label-col="{ span: 4 }"
                      :wrapper-col="{ span: 18 }">

          <a-form-model-item label="构建方式"
                             prop="type">
            <a-radio-group v-model="constructForm.type">
              <a-radio value="dockFile">
                dockFile构建镜像
              </a-radio>
              <a-radio value="dockerZip">
                镜像包构建镜像
              </a-radio>
            </a-radio-group>
          </a-form-model-item>

          <a-form-model-item v-if="constructForm.type === 'dockFile'"
                             label="镜像tag"
                             prop="tag">
            <a-input v-model="constructForm.tag"></a-input>
          </a-form-model-item>
          <a-form-model-item v-if="constructForm.type === 'dockFile'"
                             label="dockFile"
                             prop="dockFile">
            <a-upload :file-list="dockerFileList"
                      :remove="handleRemove"
                      :before-upload="beforeUpload"
                      @change="handleChange">
              <a-button type="primary"> <a-icon type="upload" />选取文件</a-button>
            </a-upload>
          </a-form-model-item>
          <a-form-model-item v-if="constructForm.type === 'dockFile'"
                             label="工作空间文件">

            <a-upload :file-list="workSpaceFileList"
                      :remove="handleWorkSpaceRemove"
                      :before-upload="beforeWorkSpaceUpload"
                      @change="handleWorkSpaceChange">
              <a-button type="primary"> <a-icon type="upload" />选取文件</a-button>
            </a-upload>

          </a-form-model-item>

          <a-form-model-item v-if="constructForm.type === 'dockerZip'"
                             label="镜像包"
                             prop="dockzipFormFile">
            <a-upload :file-list="dockerZipFileList"
                      :remove="handleDockerZipRemove"
                      :before-upload="beforeDockerZipUpload"
                      @change="handleDockerZipChange">
              <a-button type="primary"> <a-icon type="upload" />选取文件</a-button>
            </a-upload>
          </a-form-model-item>
        </a-form-model>
      </div>
    </a-modal>

  </div>
</template>
<script>
import { parseTime, renderSize } from "@/views/cloud-platform/utils/const";
import { dockerImageCreateContainer, dockerImagePullImage, dockerImageRemove, dockerImagesList, dockerImageBatchRemove } from "@/views/cloud-platform/api/docker-api";
import { constructImages, constructZipImages, downloadImages } from "@/views/cloud-platform/api/system/assets-docker";
import PullImageLog from "@/views/cloud-platform/pages/docker/pull-image-log";
import BuildContainer from "./buildContainer.vue";

import { Loading } from 'element-ui'

export default {
  components: {
    PullImageLog,
    BuildContainer,
  },
  props: {
    id: {
      type: String,
      default: "",
    },
    urlPrefix: {
      type: String,
    },
    machineDockerId: {
      type: String,
      default: "",
    },
  },
  data () {
    let validateFile = (rule, value, callback) => {
      if (this.dockerFileList.length == 0) {
        callback(new Error('请上传文件'));
      } else {
        callback();
      }
    }
    let validateZipFile = (rule, value, callback) => {
      if (this.dockerZipFileList.length == 0) {
        callback(new Error('请上传文件'));
      } else {
        callback();
      }
    }
    return {
      dockerZipFileList: [],
      workSpaceFileList: [],
      dockerFileList: [],
      constructForm: {
        type: 'dockFile'
      },
      constructVisivle: false,
      list: [],
      loading: false,
      listQuery: {
        showAll: false,
      },
      logVisible: false,
      pullImageName: "",
      renderSize,
      temp: {},
      rules: {
        tag: [
          { required: true, message: "容器名称必填", trigger: "blur" },
        ],
        dockFile: [
          { validator: validateFile, message: "请上传文件", trigger: 'change', required: true }
        ],
        dockzipFormFile: [
          { validator: validateZipFile, message: "请上传文件", trigger: 'change', required: true }
        ]
      },
      columns: [
        { title: "序号", width: 80, ellipsis: true, align: "center", customRender: (text, record, index) => `${index + 1}` },
        { title: "名称", dataIndex: "repoTags", ellipsis: true, scopedSlots: { customRender: "repoTags" } },
        { title: "镜像ID", dataIndex: "id", ellipsis: true, width: 140, align: "center", scopedSlots: { customRender: "id" } },
        { title: "父级ID", dataIndex: "parentId", ellipsis: true, width: 140, align: "center", scopedSlots: { customRender: "id" } },
        { title: "占用空间", dataIndex: "size", ellipsis: true, width: 120, scopedSlots: { customRender: "size" } },
        {
          title: "创建时间",
          dataIndex: "created",
          sorter: (a, b) => new Number(a.created) - new Number(b.created),
          sortDirections: ["descend", "ascend"],
          defaultSortOrder: "descend",
          ellipsis: true,
          customRender: (text) => {
            return parseTime(text);
          },
          width: 180,
        },

        { title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: 140 },
      ],
      action: {
        remove: {
          msg: "您确定要删除当前镜像吗？",
          api: dockerImageRemove,
        },
      },
      buildVisible: false,
      tableSelections: [],
    };
  },
  computed: {
    reqDataId () {
      return this.id || this.machineDockerId;
    },
    rowSelection () {
      return {
        onChange: (selectedRowKeys) => {
          this.tableSelections = selectedRowKeys;
        },
        selectedRowKeys: this.tableSelections,
      };
    },
  },
  mounted () {
    this.loadData();
  },
  methods: {
    handleDowload (record) {
      this.$confirm("确定下载此镜像吗？", "系统提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
      }).then(() => {
        let downloadLoadingInstance = Loading.service({ text: "正在下载镜像，请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
        const tag = record.repoTags.join(" ")

        downloadImages(this.reqDataId, tag).then(res => {
          this.$download.saveAs(res, 'saveimages.tar')
          downloadLoadingInstance.close()
        })
      });

    },
    handleDockerZipRemove (file) {
      const index = this.dockerZipFileList.indexOf(file);
      const newFileList = this.dockerZipFileList.slice();
      newFileList.splice(index, 1);

      this.dockerZipFileList = newFileList;
    },
    beforeDockerZipUpload (file) {
      this.dockerZipFileList = [...this.dockerZipFileList, file]
      return false
    },
    handleDockerZipChange (info) {
      let fileList = [...info.fileList];
      fileList = fileList.slice(-1);
      this.dockerZipFileList = fileList;
    },
    handleWorkSpaceChange (info) {
      let fileList = [...info.fileList];
      fileList = fileList.slice(-1);
      this.workSpaceFileList = fileList;
    },
    beforeWorkSpaceUpload (file) {
      this.workSpaceFileList = [...this.workSpaceFileList, file]
      return false
    },
    handleWorkSpaceRemove (file) {
      const index = this.workSpaceFileList.indexOf(file);
      const newFileList = this.workSpaceFileList.slice();
      newFileList.splice(index, 1);

      this.workSpaceFileList = newFileList;
    },
    handleChange (info) {
      let fileList = [...info.fileList];
      if (fileList[0] && fileList[0].name === 'Dockerfile') {
        fileList = fileList.slice(-1);
        this.dockerFileList = fileList;
      } else {
        info.fileList = []
        this.dockerFileList = []
        this.$message.warning('上传文件名必须为Dockerfile')
      }
    },
    handleRemove (file) {
      const index = this.dockerFileList.indexOf(file);
      const newFileList = this.dockerFileList.slice();
      newFileList.splice(index, 1);

      this.dockerFileList = newFileList;
    },
    beforeUpload (file) {
      this.dockerFileList = [...this.dockerFileList, file]
      return false
    },
    // 构建镜像
    constructImage () {
      this.constructVisivle = true
    },
    handleOk () {
      this.$refs.constructForm.validate(valid => {
        if (valid) {

          let loadingInstance = Loading.service({ text: "正在构建镜像，请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })

          let formData = new FormData()
          if (this.constructForm.type === 'dockFile') {
            console.log('this.dockerFileList', this.dockerFileList)
            formData.append('files', this.dockerFileList[0].originFileObj)
            if (this.workSpaceFileList.length != 0) {
              formData.append('files', this.workSpaceFileList[0].originFileObj)
            }
            constructImages(this.reqDataId, this.constructForm.tag, formData).then(res => {
              if (res.code == 200) {
                this.$message.success('构建镜像成功')
                this.handleCancel()
                this.loadData();
                loadingInstance.close()
              } else {
                loadingInstance.close()
              }
            })
          } else {
            let formData = new FormData()
            formData.append('file', this.dockerZipFileList[0].originFileObj)
            constructZipImages(this.reqDataId, formData).then(res => {
              if (res.code == 200) {
                this.$message.success('构建镜像成功')
                this.handleCancel()
                this.loadData();
                loadingInstance.close()
              } else {
                loadingInstance.close()
              }
            })
          }

        } else {
          return false
        }
      })
    },
    handleCancel () {
      this.constructForm = {
        type: 'dockFile'
      }
      this.dockerFileList = []
      this.workSpaceFileList = []
      this.dockerZipFileList = []
      this.constructVisivle = false
    },
    // 加载数据
    loadData () {
      this.loading = true;
      //this.listQuery.page = pointerEvent?.altKey || pointerEvent?.ctrlKey ? 1 : this.listQuery.page;
      this.listQuery.id = this.reqDataId;
      dockerImagesList(this.urlPrefix, this.listQuery).then((res) => {
        if (res.code === 200) {
          this.list = res.data;
        }
        this.loading = false;
      });
    },
    doAction (record, actionKey) {
      const action = this.action[actionKey];
      if (!action) {
        return;
      }
      this.$confirm(action.msg, "系统提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
      }).then(() => {
        // 组装参数
        const params = {
          id: this.reqDataId,
          imageId: record.id,
        };
        action.api(this.urlPrefix, params).then((res) => {
          if (res.code === 200) {
            this.$notification.success({
              message: res.msg,
            });
            this.loadData();
          }
        });
      });
    },
    tryPull (record) {
      const repoTags = record?.repoTags[0];
      if (!repoTags) {
        this.$notification.error({
          message: "镜像名称不正确 不能更新",
        });
        return;
      }
      this.pullImageName = repoTags;
      this.pullImage();
    },
    // 构建镜像
    createContainer (record) {
      this.temp = Object.assign({}, record);
      this.buildVisible = true;
    },
    // 创建容器
    handleBuildOk () {
      this.$refs["editForm"].validate((valid) => {
        if (!valid) {
          return false;
        }
        const temp = {
          id: this.reqDataId,
          autorun: this.temp.autorun,
          imageId: this.temp.imageId,
          name: this.temp.name,
          env: {},
          commands: [],
          networkMode: this.temp.networkMode,
          privileged: this.temp.privileged,
          restartPolicy: this.temp.restartPolicy,
          labels: this.temp.labels,
          runtime: this.temp.runtime,
          hostname: this.temp.hostname,
          storageOpt: {},
        };
        temp.volumes = (this.temp.volumes || [])
          .filter((item) => {
            return item.host;
          })
          .map((item) => {
            return item.host + ":" + item.container;
          })
          .join(",");
        // 处理端口
        temp.exposedPorts = (this.temp.exposedPorts || [])
          .filter((item) => {
            return item.publicPort && item.ip;
          })
          .map((item) => {
            return item.ip + ":" + item.publicPort + ":" + item.port;
          })
          .join(",");
        // 环境变量
        this.temp.env.forEach((item) => {
          if (item.key && item.key) {
            temp.env[item.key] = item.value;
          }
        });
        this.temp.storageOpt.forEach((item) => {
          if (item.key && item.key) {
            temp.storageOpt[item.key] = item.value;
          }
        });
        //
        temp.commands = (this.temp.commands || []).map((item) => {
          return item.value || "";
        });
        dockerImageCreateContainer(this.urlPrefix, temp).then((res) => {
          if (res.code === 200) {
            this.$notification.success({
              message: res.msg,
            });
            this.buildVisible = false;
          }
        });
      });
    },
    // 拉取镜像
    pullImage () {
      if (!this.pullImageName) {
        this.$notification.warn({
          message: "请填写要拉取的镜像名称",
        });
        return;
      }
      dockerImagePullImage(this.urlPrefix, {
        id: this.reqDataId,
        repository: this.pullImageName,
      }).then((res) => {
        if (res.code === 200) {
          this.logVisible = true;
          this.temp = {
            id: res.data,
          };
        }
      });
    },
    batchDelete () {
      let ids = this.tableSelections;
      this.$confirm("真的要批量删除选择的镜像吗？已经被容器使用的镜像无法删除！", "系统提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
      }).then(() => {
        // 组装参数
        const params = {
          id: this.reqDataId,
          imagesIds: ids.join(","),
        };
        dockerImageBatchRemove(this.urlPrefix, params).then((res) => {
          if (res.code === 200) {
            this.$notification.success({
              message: res.msg,
            });
            this.loadData();
          }
        });
      });
    },
  },
};
</script>
